/**
 * @file MessageRRQ.cpp
 * @author Karol Kulesza
 *
 * Implementacja klasy odpowiadającej za obsługę żądania czytania RRQ otrzymanego od klienta.
 */

#include "MessageRRQ.h"
#include "../Log.h"
#include "../FileList.h"
#include "../structures.h"
#include "../MacCollector.h"


namespace tftp_server
{

MessageRRQ::MessageRRQ(ClientController *clientController_, Package package_)
	:clientController(clientController_), package(package_)

{
	;

}

MessageRRQ::~MessageRRQ()
{

}

void MessageRRQ::execute() const
{
	int recvblknum = 0;
	int nextblknum = 0;
	char sendbuff[512];
	clientController->setLastSend(512);
	clientController->setNextBlockNumber(nextblknum);

	string str(clientController->getFileName());
	MAC mac = clientController->findMac(IP(clientController->getIp()));
	char mode = checkMode(clientController->getMode());
	if(mode == 'o')
	{
		Loger::getInstance().send(Log("MessageRRQ: wrong mode recieved from client: " + clientController->getIp(), 2));
		Package errorPackage;
		char temp[] = "wrong mode recieved";
		errorPackage.setError(ERR_UNDEF,temp);
		clientController->send(errorPackage);
		clientController->exit(-1);
		return;
	}

	File* file = FileList::getInstance().getFile(clientController->getIp(), mac ,str, mode);
	if(file->isNull())
	{
	    Loger::getInstance().send(Log("MessageRRQ: File " + string(clientController->getFileName()) + 
	    		" is Null, client IP: " + clientController->getIp(), 2));
	    Package errorPackage;
	    char temp[] = "File is Null";
	    errorPackage.setError(ERR_ACCESS,temp);
	    clientController->send(errorPackage);
	    clientController->exit(-1);
	    return;
	}

	if(!file->isExist())
	{
		Loger::getInstance().send(Log("MessageRRQ: File " + string(clientController->getFileName()) 
				+ " not found, client IP: " + clientController->getIp(), 2));
		Package errorPackage;
		char temp[] = "File not found";
		errorPackage.setError(ERR_NOFILE,temp);
		clientController->send(errorPackage);
		clientController->exit(-1);
		return;
	}

	if(!file->isAccessible())
	{
		Loger::getInstance().send(Log("MessageRRQ: Access violation to File " + string(clientController->getFileName())
				+ ", client IP: " + clientController->getIp(), 2));
		Package errorPackage;
		char temp[] = "Access violation";
		errorPackage.setError(ERR_ACCESS,temp);
		clientController->send(errorPackage);
		clientController->exit(-1);
		return;
	}

	int size = file->getFragment(MAXDATA*recvblknum, MAXDATA, sendbuff);
	int temp = nextblknum +1;
	clientController->setLastSend(size);
	clientController->setNextBlockNumber(temp);

	Package dataPackage;
	dataPackage.setData(temp, sendbuff, size);
	clientController->send(dataPackage);
	delete file;
}

}